package com.card.hwatt.core;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver;

public class RequestParamMethodArgumentResolver extends
		AbstractNamedValueMethodArgumentResolver {

	public RequestParamMethodArgumentResolver(
			ConfigurableBeanFactory beanFactory, boolean useDefaultResolution) {
		super(beanFactory);
	}

	public RequestParamMethodArgumentResolver() {
		super(null);
	}

	public boolean supportsParameter(MethodParameter parameter) {
		return parameter.hasParameterAnnotation(RequestJsonParam.class);
	}

	@Override
	protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
		RequestJsonParam annotation = parameter
				.getParameterAnnotation(RequestJsonParam.class);
		return (annotation != null) ? new RequestParamNamedValueInfo(annotation)
				: new RequestParamNamedValueInfo();
	}

	@Override
	protected Object resolveName(String name, MethodParameter parameter,
			NativeWebRequest webRequest) throws Exception {
		HttpServletRequest servletRequest = webRequest
				.getNativeRequest(HttpServletRequest.class);
		String json = servletRequest.getParameter(name);
		if (StringUtils.isEmpty(json)) {
			return null;
		}

		ObjectMapper objectMapper = new ObjectMapper();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		objectMapper.setDateFormat(df);

		Class<?> clz = parameter.getParameterType();
		Object arg = objectMapper.readValue(json, clz);
		return arg;
	}

	@Override
	protected void handleMissingValue(String paramName,
			MethodParameter parameter) throws ServletException {
		throw new MissingServletRequestParameterException(paramName, parameter
				.getParameterType().getSimpleName());
	}

	private class RequestParamNamedValueInfo extends NamedValueInfo {

		private RequestParamNamedValueInfo() {
			super("", false, null);
		}

		private RequestParamNamedValueInfo(RequestJsonParam annotation) {
			super(annotation.value(), annotation.required(), null);
		}
	}
}